home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- *
- * NSSDC/CDF CDF 'put' operations.
- *
- * Version 1.0, 14-Feb-92, ST Systems (STX)
- *
- * Modification history:
- *
- * V1.0 14-Feb-92, J Love Original version (was part of `cdflib.c').
- *
- ******************************************************************************/
-
- #include "cdflib.h"
-
- /******************************************************************************
- * CDFput.
- ******************************************************************************/
-
- CDFstatus CDFput (ap, item, fnc)
- va_list *ap;
- long item;
- long *fnc;
- {
- CDFstatus Pstatus = CDF_OK;
- CDFstatus Tstatus;
-
- switch (item) {
- case CDF_ARRAY_: {
- long numDims;
- long *dimSizes;
- long i;
- long Nbytes;
-
- numDims = va_arg (*ap, long);
- dimSizes = va_arg (*ap, long *);
-
- if (_CURcdf == NULL) return NO_CDF_SELECTED;
- if (_CURcdf->CDR.Version == 1) return ILLEGAL_ON_V1_CDF;
- if (_CURcdf->GDR.NumVar > 0) return CANNOT_CHANGE;
- if (numDims < 0 || numDims > CDF_MAX_DIMS) return
- BAD_NUM_DIMS;
- for (i = 0; i < numDims; i++)
- if (dimSizes[i] < 1) return BAD_DIM_SIZE;
-
- if (_CURcdf->status == CDF_READ_ONLY) {
- Tstatus = ReopenCDFforWrite (_CURcdf);
- STATUSdisp (Tstatus, Pstatus);
- }
-
- if (numDims != _CURcdf->GDR.NumDims) {
- /*** mark current GDR as unused ***/
-
- WASTErecord (_CURcdf->fp, _CURcdf->GDRoffset,
- _CURcdf->GDR.RecordSize);
-
- /*** allocate new GDR (and point CDR to it) ***/
-
- _CURcdf->GDRoffset = _CURcdf->GDR.eof;
- _CURcdf->CDR.GDRoffset = _CURcdf->GDRoffset;
- _CURcdf->GDR.RecordSize = GDR_BASE_SIZE +
- numDims*sizeof(Int32);
- _CURcdf->GDR.eof += _CURcdf->GDR.RecordSize;
- }
-
- _CURcdf->GDR.NumDims = numDims;
-
- if (_CURcdf->GDR.DimSizes != NULL)
- free (_CURcdf->GDR.DimSizes);
-
- if (numDims > 0) {
- _CURcdf->GDR.DimSizes = (Int32 *) malloc (numDims * sizeof(Int32));
- if (_CURcdf->GDR.DimSizes == NULL) return BAD_MALLOC;
- for (i = 0; i < numDims; i++)
- _CURcdf->GDR.DimSizes[i] = dimSizes[i];
- }
- else
- _CURcdf->GDR.DimSizes = NULL;
-
- /*** the following are reset whenever the ARRAY is changed ***/
-
- _CURcdf->recnum = 0;
- _CURcdf->reccount = 1;
- _CURcdf->recinterval = 1;
-
- if (_CURcdf->indices != NULL) free (_CURcdf->indices);
- if (_CURcdf->counts != NULL) free (_CURcdf->counts);
- if (_CURcdf->intervals != NULL) free (_CURcdf->intervals);
-
- if (numDims > 0) {
- Nbytes = numDims * sizeof(long);
-
- _CURcdf->indices = (long *) malloc (Nbytes);
- if (_CURcdf->indices == NULL) return BAD_MALLOC;
- _CURcdf->counts = (long *) malloc (Nbytes);
- if (_CURcdf->counts == NULL) return BAD_MALLOC;
- _CURcdf->intervals = (long *) malloc (Nbytes);
- if (_CURcdf->intervals == NULL) return BAD_MALLOC;
-
- for (i = 0; i < numDims; i++) {
- _CURcdf->indices[i] = 0;
- _CURcdf->counts[i] = 1;
- _CURcdf->intervals[i] = 1;
- }
- }
-
- break;
- }
- case CDF_ENCODING_: {
- long encoding;
- long actualEncoding;
- struct attrSTRUCT *Attr;
- struct varSTRUCT *Var;
-
- encoding = va_arg (*ap, long);
-
- if (_CURcdf == NULL) return NO_CDF_SELECTED;
- if (_CURcdf->CDR.Version == 1) return ILLEGAL_ON_V1_CDF;
-
- /*** can't change if any variables have been written
- to (including fill values) ***/
-
- Var = _CURcdf->varHead;
- while (Var != NULL) {
- if (Var->VDR.MaxRec > -1 || bitset(Var->VDR.Flags,VAR_FILLVALUE_BIT)) {
- return CANNOT_CHANGE;
- }
- Var = Var->varNext;
- }
-
- /*** can't change if any attribute entries have been Put ***/
-
- Attr = _CURcdf->attrHead;
- while (Attr != NULL) {
- if (Attr->ADR.NumEntries > 0) return CANNOT_CHANGE;
- Attr = Attr->attrNext;
- }
-
- if ( ! validEncoding(encoding,&actualEncoding)) return BAD_ENCODING;
-
- if (_CURcdf->status == CDF_READ_ONLY) {
- Tstatus = ReopenCDFforWrite (_CURcdf);
- STATUSdisp (Tstatus, Pstatus);
- }
-
- _CURcdf->CDR.Encoding = actualEncoding;
-
- break;
- }
- case CDF_MAJORITY_: {
- long majority;
- struct varSTRUCT *Var;
-
- majority = va_arg (*ap,long);
-
- if (_CURcdf == NULL) return NO_CDF_SELECTED;
- if (_CURcdf->CDR.Version == 1) return ILLEGAL_ON_V1_CDF;
-
- Var = _CURcdf->varHead;
- while (Var != NULL) {
- if (Var->VDR.MaxRec > -1) return CANNOT_CHANGE;
- Var = Var->varNext;
- }
-
- if (majority != ROW_MAJOR && majority != COL_MAJOR) return BAD_MAJORITY;
-
- if (_CURcdf->status == CDF_READ_ONLY) {
- Tstatus = ReopenCDFforWrite (_CURcdf);
- STATUSdisp (Tstatus, Pstatus);
- }
-
- if (majority == ROW_MAJOR)
- setbit(_CURcdf->CDR.Flags,CDF_MAJORITY_BIT);
- else
- clrbit(_CURcdf->CDR.Flags,CDF_MAJORITY_BIT);
-
- break;
- }
- case CDF_FORMAT_: {
- long format;
-
- format = va_arg (*ap,long);
-
- if (_CURcdf == NULL) return NO_CDF_SELECTED;
- if (_CURcdf->CDR.Version == 1) return ILLEGAL_ON_V1_CDF;
- if(_CURcdf->GDR.NumVar > 0) return CANNOT_CHANGE;
- if (format != SINGLE_FILE && format != MULTI_FILE) return BAD_FORMAT;
-
- if (_CURcdf->status == CDF_READ_ONLY) {
- Tstatus = ReopenCDFforWrite (_CURcdf);
- STATUSdisp (Tstatus, Pstatus);
- }
-
- if (format == SINGLE_FILE)
- setbit(_CURcdf->CDR.Flags,CDF_FORMAT_BIT);
- else
- clrbit(_CURcdf->CDR.Flags,CDF_FORMAT_BIT);
-
- break;
- }
- case VAR_NAME_: {
- char *varName;
- char tmpname[CDF_VAR_NAME_LEN+1];
- long i;
-
- varName = va_arg (*ap, char *);
-
- if (_CURcdf == NULL) return NO_CDF_SELECTED;
- if (_CURcdf->CURvar == NULL) return NO_VAR_SELECTED;
- if (_CURcdf->CDR.Version == 1) return ILLEGAL_ON_V1_CDF;
-
- if (strlen(varName) > CDF_VAR_NAME_LEN) {
- strncpy (tmpname, varName, CDF_VAR_NAME_LEN);
- tmpname[CDF_VAR_NAME_LEN] = NUL;
- STATUSdisp (VAR_NAME_TRUNC, Pstatus);
- }
- else
- strcpy (tmpname, varName);
-
- if ( ! validVarName(tmpname)) return BAD_VAR_NAME;
-
- for (i = 0; i < CDF_MAX_VARS; i++)
- if (_CURcdf->var[i] != NULL)
- if (strcmpITB(_CURcdf->var[i]->VDR.Name,tmpname) == 0)
- return VAR_EXISTS;
-
- if (_CURcdf->status == CDF_READ_ONLY) {
- Tstatus = ReopenCDFforWrite (_CURcdf);
- STATUSdisp (Tstatus, Pstatus);
- }
-
- strcpy (_CURcdf->CURvar->VDR.Name, tmpname);
-
- break;
- }
- case VAR_DATASPEC_: {
- long dataType;
- long numElements;
- struct varSTRUCT *Var;
-
- dataType = va_arg (*ap, long);
- numElements = va_arg (*ap, long);
-
- if (_CURcdf == NULL) return NO_CDF_SELECTED;
- if (_CURcdf->CURvar == NULL) return NO_VAR_SELECTED;
- if (_CURcdf->CDR.Version == 1) return ILLEGAL_ON_V1_CDF;
- if ( ! validDataType(dataType)) return BAD_DATA_TYPE;
- if (numElements < 1) return BAD_NUM_ELEMS;
-
- if (dataType != CDF_CHAR && dataType != CDF_UCHAR)
- if (numElements != 1) return BAD_NUM_ELEMS;
-
- Var = _CURcdf->CURvar;
-
- /***********************************************************
- * If the data types are not equivalent or the number of
- * elements are different, then check for the following:
- * 1) if any records have been written
- * 2) if a fill value has been specified
- * If either is true, then the data spec. cannot be changed.
- ***********************************************************/
-
- if ((_CDFequivTypes[dataType] !=
- _CDFequivTypes[Var->VDR.DataType]) ||
- numElements != Var->VDR.NumElem) {
- if (Var->VDR.MaxRec > -1) return CANNOT_CHANGE;
- if (bitset(Var->VDR.Flags,VAR_FILLVALUE_BIT)) return CANNOT_CHANGE;
- }
-
- if (_CURcdf->status == CDF_READ_ONLY) {
- Tstatus = ReopenCDFforWrite (_CURcdf);
- STATUSdisp (Tstatus, Pstatus);
- }
-
- Var->VDR.DataType = dataType;
- Var->VDR.NumElem = numElements;
-
- calcVarParms (_CURcdf, Var); /* recalculate */
-
- break;
- }
- case VAR_RECVARY_: {
- long recVariance;
-
- recVariance = va_arg (*ap, long);
-
- if (_CURcdf == NULL) return NO_CDF_SELECTED;
- if (_CURcdf->CURvar == NULL) return NO_VAR_SELECTED;
- if (_CURcdf->CDR.Version == 1) return ILLEGAL_ON_V1_CDF;
-
- /* Can't change if any records have been Put */
-
- if (_CURcdf->CURvar->VDR.MaxRec > -1) return CANNOT_CHANGE;
-
- if (_CURcdf->status == CDF_READ_ONLY) {
- Tstatus = ReopenCDFforWrite (_CURcdf);
- STATUSdisp (Tstatus, Pstatus);
- }
-
- if (recVariance)
- setbit(_CURcdf->CURvar->VDR.Flags,VAR_RECVARY_BIT);
- else
- clrbit(_CURcdf->CURvar->VDR.Flags,VAR_RECVARY_BIT);
-
- calcVarParms (_CURcdf, _CURcdf->CURvar); /* recalculate */
-
- break;
- }
- case VAR_DIMVARYS_: {
- long *dimVarys;
- long i;
-
- dimVarys = va_arg (*ap, long *);
-
- if (_CURcdf == NULL) return NO_CDF_SELECTED;
- if (_CURcdf->CURvar == NULL) return NO_VAR_SELECTED;
- if (_CURcdf->CDR.Version == 1) return ILLEGAL_ON_V1_CDF;
-
- /* Can't change if any records have been Put */
-
- if (_CURcdf->CURvar->VDR.MaxRec > -1) return CANNOT_CHANGE;
-
- if (_CURcdf->status == CDF_READ_ONLY) {
- Tstatus = ReopenCDFforWrite (_CURcdf);
- STATUSdisp (Tstatus, Pstatus);
- }
-
- for (i = 0; i < _CURcdf->GDR.NumDims; i++)
- if (dimVarys[i])
- _CURcdf->CURvar->VDR.DimVarys[i] = VARY;
- else
- _CURcdf->CURvar->VDR.DimVarys[i] = NOVARY;
-
- calcVarParms (_CURcdf, _CURcdf->CURvar); /* recalculate */
-
- break;
- }
- case VAR_FILLVALUE_: {
- void *fillValue;
- struct varSTRUCT *Var;
- struct varSTRUCT *prevVar;
-
- fillValue = va_arg (*ap, void *);
-
- if (_CURcdf == NULL) return NO_CDF_SELECTED;
- if (_CURcdf->CURvar == NULL) return NO_VAR_SELECTED;
- if (_CURcdf->CDR.Version == 1) return ILLEGAL_ON_V1_CDF;
-
- if (_CURcdf->status == CDF_READ_ONLY) {
- Tstatus = ReopenCDFforWrite (_CURcdf);
- STATUSdisp (Tstatus, Pstatus);
- }
-
- Var = _CURcdf->CURvar;
-
- if (bitset(Var->VDR.Flags,VAR_FILLVALUE_BIT))
- memmove (Var->VDR.FillValue, fillValue, Var->NvalueBytes);
- else {
- setbit (Var->VDR.Flags, VAR_FILLVALUE_BIT);
- Var->VDR.FillValue = (void *) malloc (Var->NvalueBytes);
- if (Var->VDR.FillValue == NULL) return BAD_MALLOC;
- memmove (Var->VDR.FillValue, fillValue, Var->NvalueBytes);
-
- /*********************************************************
- * If this VDR is the last record in the .cdf file, then
- * just extend the record. Otherwise, waste this VDR and
- * create a new one. This is checked because it is very
- * likely that the fill value will be specified soon after
- * the variable is created.
- *********************************************************/
-
- if (Var->VDRoffset + Var->VDR.RecordSize == _CURcdf->GDR.eof) {
- Var->VDR.RecordSize += Var->NvalueBytes;
- _CURcdf->GDR.eof += Var->NvalueBytes;
- }
- else {
- WASTErecord (_CURcdf->fp, Var->VDRoffset,
- Var->VDR.RecordSize);
- Var->VDRoffset = _CURcdf->GDR.eof;
-
- FINDprevVar (_CURcdf, Var, prevVar);
-
- if (prevVar == NULL)
- _CURcdf->GDR.VDRhead = Var->VDRoffset;
- else
- prevVar->VDR.VDRnext = Var->VDRoffset;
-
- Var->VDR.RecordSize += Var->NvalueBytes;
- _CURcdf->GDR.eof += Var->VDR.RecordSize;
- }
- }
-
- break;
- }
- case VAR_INITIALRECS_: {
- long NinitialRecs;
- long phyRecNum;
- struct varSTRUCT *Var;
-
- NinitialRecs = va_arg (*ap, long);
-
- if (_CURcdf == NULL) return NO_CDF_SELECTED;
- if (_CURcdf->CURvar == NULL) return NO_VAR_SELECTED;
- if (_CURcdf->CDR.Version == 1) return ILLEGAL_ON_V1_CDF;
-
- /* Can't set if any records have been Put */
-
- if (_CURcdf->CURvar->VDR.MaxRec > -1) return CANNOT_CHANGE;
-
- if (_CURcdf->status == CDF_READ_ONLY) {
- Tstatus = ReopenCDFforWrite (_CURcdf);
- STATUSdisp (Tstatus, Pstatus);
- }
-
- if (NinitialRecs < 1) return BAD_INITIAL_RECS;
-
- Var = _CURcdf->CURvar;
-
- if (Var->status == VAR_CLOSED) {
- Tstatus = OpenVar (_CURcdf, Var);
- STATUSdisp (Tstatus, Pstatus);
- }
-
- if (bitset(Var->VDR.Flags,VAR_RECVARY_BIT))
- phyRecNum = NinitialRecs - 1;
- else
- phyRecNum = 0;
-
- Tstatus = AllocateRecords (_CURcdf, Var, phyRecNum, TRUE);
- STATUSdisp (Tstatus, Pstatus);
-
- Var->VDR.MaxRec = phyRecNum;
-
- if (Var->VDR.MaxRec > _CURcdf->GDR.MaxRec)
- _CURcdf->GDR.MaxRec = Var->VDR.MaxRec;
-
- break;
- }
- case VAR_EXTENDRECS_: {
- long NextendRecs;
-
- NextendRecs = va_arg (*ap, long);
-
- if (_CURcdf == NULL) return NO_CDF_SELECTED;
- if (_CURcdf->CURvar == NULL) return NO_VAR_SELECTED;
- if (_CURcdf->CDR.Version == 1) return ILLEGAL_ON_V1_CDF;
-
- if (_CURcdf->status == CDF_READ_ONLY) {
- Tstatus = ReopenCDFforWrite (_CURcdf);
- STATUSdisp (Tstatus, Pstatus);
- }
-
- if (NextendRecs < 0) return BAD_EXTEND_RECS;
- /* 0 is valid meaning that the default is to be used */
-
- _CURcdf->CURvar->VDR.NextendRecs = NextendRecs;
- break;
- }
- case VAR_DATA_: {
- long offset, phyRecNum, recOffset, indicesOffset;
- long N;
- char *value;
- struct varSTRUCT *Var;
-
- if (_CURcdf == NULL) return NO_CDF_SELECTED;
- if (_CURcdf->CURvar == NULL) return NO_VAR_SELECTED;
-
- if (_CURcdf->status == CDF_READ_ONLY) {
- Tstatus = ReopenCDFforWrite (_CURcdf);
- STATUSdisp (Tstatus, Pstatus);
- }
-
- Var = _CURcdf->CURvar;
-
- if (Var->status == VAR_CLOSED) {
- Tstatus = OpenVar (_CURcdf, Var);
- STATUSdisp (Tstatus, Pstatus);
- }
-
- Var->accessed_at = _CDFpseudo_clock++;
-
- value = va_arg (*ap, char *);
-
- /************************************************************
- * Compute physical record number.
- ************************************************************/
-
- if (bitclr(Var->VDR.Flags,VAR_RECVARY_BIT))
- phyRecNum = 0;
- else
- phyRecNum = _CURcdf->recnum;
-
- /************************************************************
- * Allocate records if necessary.
- ************************************************************/
-
- if (Var->VDR.MaxRec < phyRecNum) {
- #if defined(vms)
- /*** CAN'T EXTEND A V1 VECTOR FILE ***/
- if (_CURcdf->CDR.Version == 1) return ILLEGAL_ON_V1_CDF;
- #endif
- Tstatus = AllocateRecords (_CURcdf, Var, phyRecNum, FALSE);
- STATUSdisp (Tstatus, Pstatus);
-
- Var->VDR.MaxRec = phyRecNum;
-
- if (Var->VDR.MaxRec > _CURcdf->GDR.MaxRec)
- _CURcdf->GDR.MaxRec = Var->VDR.MaxRec;
- }
-
- /************************************************************
- * Put variable data value.
- ************************************************************/
-
- if (bitclr(_CURcdf->CDR.Flags,CDF_FORMAT_BIT))
- recOffset = phyRecNum * Var->NphyRecBytes;
- else
- SINGLErecOffsetB (Var, phyRecNum, recOffset);
-
- INDICESoffsetB (_CURcdf->GDR.NumDims, Var, _CURcdf->indices,
- indicesOffset);
- offset = recOffset + indicesOffset;
-
- #if defined(sun) | defined(MIPSEB) | defined(IBMRS) | defined(HP)
- Seek (Var->fp, offset, SEEK_SET);
- N = putbytes (Var->NvalueBytes, value, Var->fp);
- if (N != Var->NvalueBytes) return VAR_WRITE_ERROR;
- #endif
-
- #if defined(vax) | defined(MIPSEL) | defined(__IBMPC__)
- if (_CURcdf->CDR.Encoding == NETWORK_ENCODING) {
- void *tmpbuffer;
- double xdrbuffer;
-
- if (Var->NvalueBytes > sizeof(xdrbuffer)) {
- tmpbuffer = (void *) malloc (Var->NvalueBytes);
- if (tmpbuffer == NULL) return BAD_MALLOC;
- }
- else
- tmpbuffer = (void *) &xdrbuffer;
-
- xdr_encode (Var->VDR.DataType, Var->VDR.NumElem, value, tmpbuffer);
-
- Seek (Var->fp, offset, SEEK_SET);
- N = putbytes (Var->NvalueBytes, tmpbuffer, Var->fp);
- if (N != Var->NvalueBytes) {
- if (tmpbuffer != (void *) &xdrbuffer) free (tmpbuffer);
- return VAR_WRITE_ERROR;
- }
-
- if (tmpbuffer != (void *) &xdrbuffer) free (tmpbuffer);
- }
- else { /* HOST encoding */
- Seek (Var->fp, offset, SEEK_SET);
- N = putbytes (Var->NvalueBytes, value, Var->fp);
- if (N != Var->NvalueBytes) return VAR_WRITE_ERROR;
- }
- #endif
- break;
- }
- case VAR_HYPERDATA_: {
- long phyStartRecN, phyEndRecN;
- char *buffer;
- long i;
- struct varSTRUCT *Var;
- long Nvalues, Nbytes;
-
- if (_CURcdf == NULL) return NO_CDF_SELECTED;
- if (_CURcdf->CURvar == NULL) return NO_VAR_SELECTED;
-
- if (_CURcdf->status == CDF_READ_ONLY) {
- Tstatus = ReopenCDFforWrite (_CURcdf);
- STATUSdisp (Tstatus, Pstatus);
- }
-
- Var = _CURcdf->CURvar;
-
- if (Var->status == VAR_CLOSED) {
- Tstatus = OpenVar (_CURcdf, Var);
- STATUSdisp (Tstatus, Pstatus);
- }
-
- Var->accessed_at = _CDFpseudo_clock++;
-
- buffer = va_arg (*ap, char *);
-
- #if FULL_ERROR_CHECKING
- for (i = 0; i < _CURcdf->GDR.NumDims; i++)
- if (_CURcdf->indices[i] +
- ((_CURcdf->counts[i] - 1) *
- _CURcdf->intervals[i]) >= _CURcdf->GDR.DimSizes[i]) return
- BAD_DIM_INDEX;
-
- #if defined(__MSDOS__)
- Nvalues = _CURcdf->reccount;
- for (i = 0; i < _CURcdf->GDR.NumDims; i++) Nvalues *= _CURcdf->counts[i];
- Nbytes = Nvalues * Var->VDR.NumElem * _CDFelemSizes[Var->VDR.DataType];
- if (Nbytes > (long) 65535) return IBM_PC_OVERFLOW;
- #endif
- #endif
-
- /************************************************************
- * Compute physical record numbers (start and end).
- ************************************************************/
-
- if (bitclr(Var->VDR.Flags,VAR_RECVARY_BIT)) {
- phyStartRecN = 0;
- phyEndRecN = 0;
- }
- else {
- phyStartRecN = _CURcdf->recnum;
- phyEndRecN = phyStartRecN + (_CURcdf->reccount-1) * _CURcdf->recinterval;
- }
-
- /************************************************************
- * Allocate records if necessary.
- ************************************************************/
-
- if (Var->VDR.MaxRec < phyEndRecN) {
- #if defined(vms)
- /*** CAN'T EXTEND A V1 VECTOR FILE ***/
- if (_CURcdf->CDR.Version == 1)
- return ILLEGAL_ON_V1_CDF;
- #endif
- Tstatus = AllocateRecords (_CURcdf, Var, phyEndRecN, FALSE);
- STATUSdisp (Tstatus, Pstatus);
-
- Var->VDR.MaxRec = phyEndRecN;
-
- if (Var->VDR.MaxRec > _CURcdf->GDR.MaxRec)
- _CURcdf->GDR.MaxRec = Var->VDR.MaxRec;
- }
-
- /************************************************************
- * Put variable data value(s).
- ************************************************************/
-
- if (bitset(_CURcdf->CDR.Flags,CDF_MAJORITY_BIT))
- Tstatus = HyperAccess (Var, buffer, TRUE, FALSE);
- else
- Tstatus = HyperAccess (Var, buffer, FALSE, FALSE);
- STATUSdisp (Tstatus, Pstatus);
-
- break;
- }
- case VAR_SEQDATA_: {
- struct varSTRUCT *Var;
- void *value;
- long N;
- long recOffset;
- long offset;
- long recN; /* record number value is in */
-
- value = va_arg (*ap, char *);
-
- if (_CURcdf == NULL) return NO_CDF_SELECTED;
- if (_CURcdf->CURvar == NULL) return NO_VAR_SELECTED;
-
- if (_CURcdf->status == CDF_READ_ONLY) {
- Tstatus = ReopenCDFforWrite (_CURcdf);
- STATUSdisp (Tstatus, Pstatus);
- }
-
- Var = _CURcdf->CURvar;
-
- if (Var->status == VAR_CLOSED) {
- Tstatus = OpenVar (_CURcdf, Var);
- STATUSdisp (Tstatus, Pstatus);
- }
-
- Var->accessed_at = _CDFpseudo_clock++;
-
- recN = Var->seqValueOffset / Var->NphyRecValues;
-
- if (recN > Var->VDR.MaxRec) {
- if (bitclr(Var->VDR.Flags,VAR_RECVARY_BIT) && recN > 0)
- return END_OF_VAR;
-
- if (_CURcdf->CDR.Version == 1)
- return ILLEGAL_ON_V1_CDF;
-
- Tstatus = AllocateRecords (_CURcdf, Var, recN, FALSE);
- STATUSdisp (Tstatus, Pstatus);
-
- Var->VDR.MaxRec = recN;
- _CURcdf->GDR.MaxRec = Maximum (_CURcdf->GDR.MaxRec, Var->VDR.MaxRec);
- }
-
- if (bitclr(_CURcdf->CDR.Flags,CDF_FORMAT_BIT))
- offset = Var->seqValueOffset * Var->NvalueBytes;
- else {
- SINGLErecOffsetB (Var, recN, recOffset);
- offset = recOffset + (Var->seqValueOffset % Var->NphyRecValues) *
- Var->NvalueBytes;
- }
-
- #if defined(sun) | defined(MIPSEB) | defined(IBMRS) | defined(HP)
- Seek (Var->fp, offset, SEEK_SET);
- N = putbytes (Var->NvalueBytes, value, Var->fp);
- if (N != Var->NvalueBytes) return VAR_WRITE_ERROR;
- #endif
-
- #if defined(vax) | defined(MIPSEL) | defined(__IBMPC__)
- if (_CURcdf->CDR.Encoding == NETWORK_ENCODING) {
- void *tmpbuffer;
- double xdrbuffer;
-
- if (Var->NvalueBytes > sizeof(xdrbuffer)) {
- tmpbuffer = (void *) malloc (Var->NvalueBytes);
- if (tmpbuffer == NULL) return BAD_MALLOC;
- }
- else
- tmpbuffer = (void *) &xdrbuffer;
-
- xdr_encode (Var->VDR.DataType, Var->VDR.NumElem, value, tmpbuffer);
-
- Seek (Var->fp, offset, SEEK_SET);
- N = putbytes (Var->NvalueBytes, tmpbuffer, Var->fp);
- if (N != Var->NvalueBytes) {
- if (tmpbuffer != (void *) &xdrbuffer) free (tmpbuffer);
- return VAR_WRITE_ERROR;
- }
-
- if (tmpbuffer != (void *) &xdrbuffer) free (tmpbuffer);
- }
- else { /* HOST encoding */
- Seek (Var->fp, offset, SEEK_SET);
- N = putbytes (Var->NvalueBytes, value, Var->fp);
- if (N != Var->NvalueBytes) return VAR_WRITE_ERROR;
- }
- #endif
- Var->seqValueOffset++; /* increment to next value */
-
- break;
- }
-
- case ATTR_SCOPE_: {
- long scope;
-
- scope = va_arg (*ap, long);
-
- if (_CURcdf == NULL) return NO_CDF_SELECTED;
- if (_CURcdf->CURattr == NULL) return NO_ATTR_SELECTED;
- if (_CURcdf->CDR.Version == 1) return ILLEGAL_ON_V1_CDF;
- if ( ! validAttrScope(scope)) return BAD_SCOPE;
-
- if (_CURcdf->status == CDF_READ_ONLY) {
- Tstatus = ReopenCDFforWrite (_CURcdf);
- STATUSdisp (Tstatus, Pstatus);
- }
-
- _CURcdf->CURattr->ADR.Scope = scope;
-
- break;
- }
- case ATTR_NAME_: {
- /* Make sure no other attribute with this name */
-
- char *attrname;
- char tmpname[CDF_ATTR_NAME_LEN+1];
- struct attrSTRUCT *Attr;
-
- attrname = va_arg (*ap, char *);
-
- if (_CURcdf == NULL) return NO_CDF_SELECTED;
- if (_CURcdf->CURattr == NULL) return NO_ATTR_SELECTED;
- if (_CURcdf->CDR.Version == 1) return ILLEGAL_ON_V1_CDF;
-
- if (strlen(attrname) > CDF_ATTR_NAME_LEN) {
- strncpy (tmpname, attrname, CDF_ATTR_NAME_LEN);
- tmpname[CDF_ATTR_NAME_LEN] = NUL;
- STATUSdisp (ATTR_NAME_TRUNC, Pstatus);
- }
- else
- strcpy (tmpname, attrname);
-
- if ( ! validAttrName(tmpname)) return BAD_ATTR_NAME;
-
- Attr = _CURcdf->attrHead;
- while (Attr != NULL) {
- if (strcmpITB(tmpname,Attr->ADR.Name) == 0) return ATTR_EXISTS;
- Attr = Attr->attrNext;
- }
-
- if (_CURcdf->status == CDF_READ_ONLY) {
- Tstatus = ReopenCDFforWrite (_CURcdf);
- STATUSdisp (Tstatus, Pstatus);
- }
-
- strcpy (_CURcdf->CURattr->ADR.Name, tmpname);
-
- break;
- }
- case ENTRY_DATA_: {
- long dataType;
- long numElements;
- void *value;
- struct attrSTRUCT *Attr;
- struct entrySTRUCT *Entry;
- struct entrySTRUCT *ntlEntry; /* next-to-last Entry */
- struct entrySTRUCT *prevEntry;
- long Nbytes;
-
- dataType = va_arg (*ap, long);
- numElements = va_arg (*ap, long);
- value = va_arg (*ap, void *);
-
- if (_CURcdf == NULL) return NO_CDF_SELECTED;
- if (_CURcdf->CURentryNum == RESERVED_ENTRYNUM) return NO_ENTRY_SELECTED;
- if (_CURcdf->CURattr == NULL) return NO_ATTR_SELECTED;
- if (_CURcdf->CDR.Version == 1) return ILLEGAL_ON_V1_CDF;
- if ( ! validDataType(dataType)) return BAD_DATA_TYPE;
- if (numElements < 1) return BAD_NUM_ELEMS;
-
- Nbytes = numElements * _CDFelemSizes[dataType];
-
- if (_CURcdf->status == CDF_READ_ONLY) {
- Tstatus = ReopenCDFforWrite (_CURcdf);
- STATUSdisp (Tstatus, Pstatus);
- }
-
- Attr = _CURcdf->CURattr;
- Entry = _CURcdf->CURentry;
-
- if (Entry == NULL) { /*** new entry ***/
- Entry = (struct entrySTRUCT *) malloc (sizeof(struct entrySTRUCT));
- if (Entry == NULL) return BAD_MALLOC;
-
- if (Attr->entryHead == NULL) { /* first entry */
- ntlEntry = (struct entrySTRUCT *) NULL;
- Attr->entryHead = Entry;
- Attr->entryTail = Entry;
- }
- else {
- ntlEntry = _CURcdf->CURattr->entryTail;
- Attr->entryTail->entryNext = Entry;
- Attr->entryTail = Entry;
- }
-
- Entry->entryNext = (struct entrySTRUCT *) NULL;
-
- /*** Set up AEDR ***/
-
- Entry->AEDRoffset = _CURcdf->GDR.eof;
-
- /* RecordSize calculated below */
- Entry->AEDR.RecordType = AEDR_;
- Entry->AEDR.AEDRnext = 0;
- Entry->AEDR.AttrNum = Attr->ADR.Num;
- Entry->AEDR.DataType = dataType;
- Entry->AEDR.Num = _CURcdf->CURentryNum;
- Entry->AEDR.NumElem = numElements;
-
- Entry->AEDR.rfuA = 0;
- Entry->AEDR.rfuB = 0;
- Entry->AEDR.rfuC = 0;
- Entry->AEDR.rfuD = -1;
- Entry->AEDR.rfuE = -1;
-
- Entry->AEDR.Value = (void *) malloc (Nbytes);
- if (Entry->AEDR.Value == NULL) return BAD_MALLOC; /* CLEAN UP! */
-
- memmove (Entry->AEDR.Value, value, Nbytes);
-
- Entry->AEDR.RecordSize = AEDR_BASE_SIZE + Nbytes;
-
- _CURcdf->GDR.eof += Entry->AEDR.RecordSize;
-
- /*** point next-to-last AEDR (or ADR) to this AEDR ***/
-
- if (ntlEntry == NULL)
- Attr->ADR.AEDRhead = Entry->AEDRoffset;
- else
- ntlEntry->AEDR.AEDRnext = Entry->AEDRoffset;
-
- /*** tally another entry and check if max. entry ***/
-
- Attr->ADR.NumEntries++;
- Attr->ADR.MaxEntry = Maximum (Attr->ADR.MaxEntry, Entry->AEDR.Num);
- _CURcdf->CURentry = Entry;
- }
- else { /*** entry already exists ***/
- if (Nbytes != Entry->AEDR.NumElem * _CDFelemSizes[Entry->AEDR.DataType]){
- WASTErecord (_CURcdf->fp, Entry->AEDRoffset, Entry->AEDR.RecordSize);
- Entry->AEDRoffset = _CURcdf->GDR.eof;
-
- FINDprevEntry (Attr, Entry, prevEntry);
-
- if (prevEntry == NULL)
- Attr->ADR.AEDRhead = Entry->AEDRoffset;
- else
- prevEntry->AEDR.AEDRnext = Entry->AEDRoffset;
-
- Entry->AEDR.RecordSize = AEDR_BASE_SIZE + Nbytes;
- _CURcdf->GDR.eof += Entry->AEDR.RecordSize;
- }
-
- Entry->AEDR.DataType = dataType;
- Entry->AEDR.NumElem = numElements;
-
- free (Entry->AEDR.Value);
- Entry->AEDR.Value = (void *) malloc (Nbytes);
- if (Entry->AEDR.Value == NULL) return BAD_MALLOC;
-
- memmove (Entry->AEDR.Value, value, Nbytes);
- }
-
- break;
- }
- default: {
- *fnc = item;
- break;
- }
- }
- return Pstatus;
- }
-